#ifndef MEMLOAD_H
#define MEMLOAD_H

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "mldll_global.h"

typedef void *HMEMORYMODULE;

typedef void *HMEMORYRSRC;

typedef void *HCUSTOMMODULE;

#if defined (__cplusplus) || defined (c_plusplus)
extern "C" {
#endif

typedef LPVOID (*CustomAllocFunc)(LPVOID, SIZE_T, DWORD, DWORD, void*);
typedef BOOL (*CustomFreeFunc)(LPVOID, SIZE_T, DWORD, void*);
typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);

MLDLL_EXPORT void OutputLastError(const TCHAR *msg);

/**
 * Load EXE/DLL from memory location with the given size.
 * 从给定大小的内存位置加载 EXE/DLL
 *
 * All dependencies are resolved using default LoadLibrary/GetProcAddress
 * calls through the Windows API.
 */
MLDLL_EXPORT HMEMORYMODULE MemoryLoadLibrary(const void *, size_t);

/**
 * Load EXE/DLL from memory location with the given size using custom dependency
 * resolvers.
 * 使用自定义依赖性解析器从内存位置以给定大小加载 EXE/DLL
 *
 * Dependencies will be resolved using passed callback methods.
 */
MLDLL_EXPORT HMEMORYMODULE MemoryLoadLibraryEx(const void *, size_t,
    CustomAllocFunc,
    CustomFreeFunc,
    CustomLoadLibraryFunc,
    CustomGetProcAddressFunc,
    CustomFreeLibraryFunc,
    void *);

/**
 * Get address of exported method. Supports loading both by name and by
 * ordinal value.
 * 获取导出方法的地址。 支持按名称和按序值加载。
 */
MLDLL_EXPORT FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);

/**
 * Free previously loaded EXE/DLL.
 * 释放前面已经加载的 EXE/DLL
 */
MLDLL_EXPORT void MemoryFreeLibrary(HMEMORYMODULE);

/**
 * Execute entry point (EXE only). The entry point can only be executed
 * if the EXE has been loaded to the correct base address or it could
 * be relocated (i.e. relocation information have not been stripped by
 * the linker).
 * 执行入口点(仅EXE)
 *
 * Important: calling this function will not return, i.e. once the loaded
 * EXE finished running, the process will terminate.
 *
 * Returns a negative value if the entry point could not be executed.
 */
MLDLL_EXPORT int MemoryCallEntryPoint(HMEMORYMODULE);

/**
 * Find the location of a resource with the specified type and name.
 * 查找具有指定类型和名称的资源的位置
 */
MLDLL_EXPORT HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR);

/**
 * Find the location of a resource with the specified type, name and language.
 * 查找具有指定类型，名称和语言的资源的位置
 */
MLDLL_EXPORT HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE, LPCTSTR, LPCTSTR, WORD);

/**
 * Get the size of the resource in bytes.
 * 获取资源的大小（以字节为单位）。
 */
MLDLL_EXPORT DWORD MemorySizeofResource(HMEMORYMODULE, HMEMORYRSRC);

/**
 * Get a pointer to the contents of the resource.
 * 获取指向资源内容的指针。
 */
MLDLL_EXPORT LPVOID MemoryLoadResource(HMEMORYMODULE, HMEMORYRSRC);

/**
 * Load a string resource.
 * 加载字符串资源
 */
MLDLL_EXPORT int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int);

/**
 * Load a string resource with a given language.
 * 使用给定的语言加载字符串资源。
 */
MLDLL_EXPORT int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD);

/**
* Default implementation of CustomAllocFunc that calls VirtualAlloc
* internally to allocate memory for a library
* CustomAllocFunc的默认实现，该实现在内部调用VirtualAlloc来为库分配内存
*
* This is the default as used by MemoryLoadLibrary.
*/
MLDLL_EXPORT LPVOID MemoryDefaultAlloc(LPVOID, SIZE_T, DWORD, DWORD, void *);

/**
* Default implementation of CustomFreeFunc that calls VirtualFree
* internally to free the memory used by a library
* CustomFreeFunc的默认实现，该实现在内部调用VirtualFree以释放库使用的内存
*
* This is the default as used by MemoryLoadLibrary.
*/
MLDLL_EXPORT BOOL MemoryDefaultFree(LPVOID, SIZE_T, DWORD, void *);

/**
 * Default implementation of CustomLoadLibraryFunc that calls LoadLibraryA
 * internally to load an additional libary.
 * CustomLoadLibraryFunc的默认实现，该实现在内部调用LoadLibraryA以加载其他库。
 *
 * This is the default as used by MemoryLoadLibrary.
 */
MLDLL_EXPORT HCUSTOMMODULE MemoryDefaultLoadLibrary(LPCSTR, void *);

/**
 * Default implementation of CustomGetProcAddressFunc that calls GetProcAddress
 * internally to get the address of an exported function.
 * CustomGetProcAddressFunc的默认实现，该实现在内部调用GetProcAddress以获取导出函数的地址
 *
 * This is the default as used by MemoryLoadLibrary.
 */
MLDLL_EXPORT FARPROC MemoryDefaultGetProcAddress(HCUSTOMMODULE, LPCSTR, void *);

/**
 * Default implementation of CustomFreeLibraryFunc that calls FreeLibrary
 * internally to release an additional libary.
 * 自定义FreeLibrary Func的默认实现，该功能在内部调用FreeLibrary以释放其他库
 *
 * This is the default as used by MemoryLoadLibrary.
 */
MLDLL_EXPORT void MemoryDefaultFreeLibrary(HCUSTOMMODULE, void *);

#if defined (__cplusplus) || defined (c_plusplus)
} /* End of extern "C" */
#endif

#endif // MEMLOAD_H
